package com.ruoyi.yl.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.redis.service.RedisService;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.common.domain.Activity;
import com.ruoyi.common.domain.Orders;
import com.ruoyi.common.domain.constant.RedisKey;
import com.ruoyi.system.api.constant.YlStatus;
import com.ruoyi.common.domain.dto.CommentDto;
import com.ruoyi.common.domain.dto.OrderDTO;
import com.ruoyi.common.mapper.OrdersMapper;
import com.ruoyi.yl.service.IActivityService;
import com.ruoyi.yl.service.IMerchantsService;
import com.ruoyi.yl.service.IOrdersService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 订单表，存储用户参与霸王餐活动的订单信息 服务实现类
 * </p>
 *
 * @author jiabao
 * @since 2025-06-25
 */
@Service
@Slf4j
public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, Orders> implements IOrdersService {

    @Resource
    private RedisService redisService;

    @Resource
    private IMerchantsService merchantsService;

    @Resource
    private IActivityService activityService;


    @Override
    public void verificationActivityParticipate(Long activityId) {
        Long userId = SecurityUtils.getUserId();
        String key = String.format(RedisKey.ACTIVITY_PARTICIPATE, activityId, userId);

        if (redisService.hasKey(key)) {
            throw new ServiceException("您已经参加过该活动");
        }

        List<Orders> ordersList = this.getBaseMapper().selectList(Wrappers.lambdaQuery(Orders.class)
                .eq(Orders::getActivityId, activityId)
                .eq(Orders::getUserId, userId)
                .eq(Orders::getStatus, YlStatus.ABNORMAL.getCode())

        );

        /**
         * 查询参与过的标识 不满足下面条件的都被认定为 参加过该活动
         * 1. 不等于已经取消
         * 2. 不等于已经超时
         * 3. 不等于已经退款
         */
        Orders orders = ordersList.stream()
                .filter(o ->
                        !Orders.CURRENT_TYPE.TIME_OUT.getValue().equals(o.getCurrentStatus()) &&
                                !Orders.CURRENT_TYPE.CANCELLED.getValue().equals(o.getCurrentStatus()) &&
                                !Orders.CURRENT_TYPE.REFUND.getValue().equals(o.getCurrentStatus())
                )
                .findFirst()
                .orElse(null);


        if (orders != null) {
            String lockVal = UUID.randomUUID().toString();
            redisService.setCacheObject(key, lockVal, 25L, TimeUnit.MINUTES);
            throw new ServiceException("您已经参加过该活动");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Orders create(Long activityId, Long merchantId, String orderNo) {
        Long userId = SecurityUtils.getUserId();
        Activity activity = activityService.selectActivityById(activityId);
        try {

            LocalDateTime now = LocalDateTime.now();
            Orders order = Orders.builder()
                    .userId(userId)
                    .activityId(activityId)
                    .merchantId(merchantId)
                    .status(YlStatus.NORMAL.getCode())
                    .createdAt(now)
                    .updatedAt(now)
                    .orderNo(orderNo)
                    .demandAmount(activity.getParticipatePrice())
                    .whetherComment(Orders.WHETHER_COMMENT.getRandom())
                    .currentStatus(Orders.CURRENT_TYPE.NO_PAY.getValue())
                    .build();
            this.getBaseMapper().insert(order);

            return order;

        } catch (Exception e) {
            String key = String.format(RedisKey.ACTIVITY_INVENTORY, activityId);
            redisService.increase(key, 1);
            log.error("订单创建失败:{}", e.getMessage());
            throw new ServiceException("订单创建失败");

        }
    }


    @Override
    public List<OrderDTO> selectOrderList(String currentStatus) {
        Long userId = SecurityUtils.getUserId();
        return this.getBaseMapper().selectOrder(userId, currentStatus);
    }

    @Override
    public Orders selectOrdersByActivityId(Long activityId) {

        return this.getBaseMapper().selectOne(Wrappers.lambdaQuery(Orders.class)
                .eq(Orders::getActivityId, activityId)
                .eq(Orders::getUserId, SecurityUtils.getUserId())
                .eq(Orders::getStatus, YlStatus.NORMAL.getCode())
        );
    }

    @Override
    public Orders selectOrdersByOrderNo(String orderNo) {
        return this.getBaseMapper().selectOne(Wrappers.lambdaQuery(Orders.class)
                .eq(Orders::getOrderNo, orderNo)
                .eq(Orders::getUserId, SecurityUtils.getUserId())
                .eq(Orders::getStatus, YlStatus.NORMAL.getCode())
        );
    }

    @Override
    public CommentDto getCommentInfoByOderNo(String orderNo) {
        return this.getBaseMapper().getCommentInfoByOderNo(orderNo, SecurityUtils.getUserId());
    }

    @Override
    public void updateOrderCurrentStatusByOrderNo(String orderNo, Orders.CURRENT_TYPE currentType) {
        Orders orders = this.selectByOrderNo(orderNo);

        orders.setCurrentStatus(currentType.getValue());

        this.saveOrUpdate(orders);

    }

    @Override
    public Orders selectByOrderNo(String orderNo) {
        return this.getBaseMapper().selectOne(Wrappers.lambdaQuery(Orders.class)
                .eq(Orders::getStatus, YlStatus.NORMAL.getCode())
                .eq(Orders::getOrderNo, orderNo)
        );
    }
}
